home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / sys / dos / emx / emxvga.c next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  13.3 KB  |  470 lines

  1. /* ///////////////////////////////////////////////////////////////////
  2. //  File:       emxvga.c                                     [emx+gcc]
  3. //
  4. //  Descript:   the SVGA display driver for DOS & OS/2
  5. //
  6. //  Library:    plplot
  7. //
  8. //  Requires:   emx0.8h + gcc 2.5.7
  9. //              svgakit/vesakit 1.5 (Johannes Martin)
  10. //
  11. //  Public:     plD_init_vga()
  12. //              plD_line_vga()
  13. //              plD_polyline_vga()
  14. //              plD_eop_vga()
  15. //              plD_bop_vga()
  16. //              plD_tidy_vga()
  17. //              plD_state_vga()
  18. //              plD_esc_vga()
  19. //
  20. //              pldummy_emxvga()
  21. //
  22. //  Private:    pause()
  23. //              vga_graphics()
  24. //              vga_text()
  25. //              g_mode_detect()
  26. //              fill_polygon()
  27. //
  28. //  Notes:
  29. //  0)  Since there is no *standard* graphics mode text output for emx,
  30. //      just draw a small carriage return <-| in the top-left corner.
  31. //
  32. //  1)  Only supports 256+ colour, VESA compliant, SVGA cards.
  33. //
  34. //  2)  uses `-geometry WxH+Xof+Yoff` to force a screen resolution
  35. //      * if (Xoffset > Width), use Xoffset as the VESA mode number [decimal]
  36. //      * else use Width to select a 256 colour VESA mode
  37. //           Width == 480 --> 640x480 mode
  38. //           Width == 400 --> 640x400 mode
  39. //         or
  40. //           Width == 640 and Height is the tiebreaker
  41. //      * else start at a high resolution and work downwards
  42. //
  43. //  3)  Uses color map 0, color map 1 colour selection, does polygon fills
  44. //
  45. //  Revisions:
  46. //  13 Apr 94   mjo     documented (mj olesen)
  47. //   8 Jun 94   mjo     color map 0,1 color selection, color map 0,1
  48. //                      state change (palette change), polygon fills.
  49. /////////////////////////////////////////////////////////////////// */
  50. #if defined (__EMX__) && defined (EMXVESA)      /* (emx+gcc) */
  51.  
  52. #include "plplotP.h"            /* _read_kbd() in <stdlib.h> */
  53. #include "drivers.h"
  54. #include <graph.h>
  55.  
  56. /* Function prototypes */
  57. /* INDENT OFF */
  58.  
  59. static void     pause           (void);
  60. static void     vga_text        (PLStream *);
  61. static void     vga_graphics    (PLStream *);
  62. static int      g_mode_detect   (PLStream *);
  63. static void     fill_polygon    (PLStream *);
  64.  
  65. typedef struct {
  66.     short       isPageDirty;    /* track if something has been plotted */
  67.     short       VESAmode;       /* the VESA mode number */
  68.     short       xlen;           /* g_xsize -1 */
  69.     short       ylen;           /* g_ysize -1 */
  70.     short       ncol1;          /* Number of cmap 1 colors permitted */
  71.     short       curcolor;       /* Current pen color */
  72. } vgaDev;
  73.  
  74. /* //////////////////////////////////////////////////////////////// */
  75.  
  76. /* Initializes cmap 0 */
  77. #define Cmap0Init(p)    \
  78.         g_vgapal( (unsigned char *)((p)->cmap0), 0, (p)->ncol0, 0 )
  79.  
  80. /* Initializes cmap 1 */
  81. #define Cmap1Init(p)    \
  82.         g_vgapal( (unsigned char *)((p)->cmap1), (p)->ncol0, \
  83.                 ((vgaDev *)(p)->dev)->ncol1, 0 )
  84.  
  85. #define PROMPT_COLOR    2       /* colour for pause, same as axis labels */
  86.  
  87. /* INDENT ON */
  88. /*----------------------------------------------------------------------*\
  89. * g_mode_detect()
  90. *
  91. * try a variety of display resolutions
  92. * not exactly autodetect ... but something
  93. *
  94. * check if `-geometry WxH+Xof+Yoff` was passed on the argument list
  95. *
  96. * if ( Xof > W )
  97. *   use Xof as the VESA mode number (use cautiously)
  98. * else if ( W > 0 && H > 0 )
  99. *   use W and H to select a 256 colour VESA mode
  100. * else
  101. *   start at highest resolution 256 colour VESA mode and work down
  102. *
  103. \*----------------------------------------------------------------------*/
  104. static int
  105. g_mode_detect( PLStream *pls )
  106. {                               /* ~~~~ */
  107.   vgaDev *dev;
  108.   int mode;
  109.   dev = (vgaDev *) pls->dev;
  110.  
  111. /* if geometry was passed via arg list */
  112.   if ( pls->xoffset > pls->xlength ) {
  113.     mode = pls->xoffset;        /* offset specified = VESA mode */
  114.     if ( !g_mode( mode ) ) {
  115.       fprintf( stderr, "Can\'t set VESA mode %d (0x%x)\n", mode, mode );
  116.       exit(0);
  117.     }
  118.   } else {                      /* xlength specified = X resolution */
  119.     switch ( pls->xlength ) {
  120.     case 1280:  mode = G1280x1024x256;  break;
  121.     case 1024:  mode = G1024x768x256;   break;
  122.     case 800:   mode = G800x600x256;    break;
  123.     case 640:   mode = (pls->ylength<=400)? G640x400x256: G640x480x256; break;
  124.     case 480:   mode = G640x480x256;    break;  /* easy way to get 640x480 */
  125.     case 400:   mode = G640x400x256;    break;  /* easy way to get 640x400 */
  126.     case 320:   mode = G320x200x256;    break;
  127.     default:    mode = G1280x1024x256;  /* aim for a high resolution ! */
  128.     }
  129.  
  130.     switch ( mode ) {           /* start high and work down */
  131.     case G1280x1024x256:if(g_mode(mode=G1280x1024x256)) break;
  132.     case G1024x768x256: if(g_mode(mode=G1024x768x256))  break;
  133.     case G800x600x256:  if(g_mode(mode=G800x600x256))   break;
  134.     case G640x480x256:  if(g_mode(mode=G640x480x256))   break;
  135.     case G640x400x256:  if(g_mode(mode=G640x400x256))   break;
  136.     case G320x200x256:  if(g_mode(mode=G320x200x256))   break;
  137.     default:  mode = 0;      /* no vga card ? */
  138.     }
  139.   }
  140.  
  141.   dev->VESAmode = mode;
  142. #ifdef SET_SIZE_EXPLICITLY
  143.   { short x, y, c;              /* if you don't trust g_?size, g_colors */
  144.     switch ( mode ) {
  145.     case G1280x1024x256:x = 1280; y = 1024; c = 256; break;
  146.     case G1024x768x256: x = 1024; y = 768;  c = 256; break;
  147.     case G800x600x256:  x = 800;  y = 600;  c = 256; break;
  148.     case G640x480x256:  x = 640;  y = 480;  c = 256; break;
  149.     case G640x400x256:  x = 640;  y = 400;  c = 256; break;
  150.     case G320x200x256:  x = 320;  y = 200;  c = 256; break;
  151.     default:            x = y = c = 0;
  152.     }
  153.     pls->xlength  = x;
  154.     pls->ylength  = y;
  155.     dev->ncol1    = c;
  156.   }
  157. #else
  158.   pls->xlength = g_xsize;
  159.   pls->ylength = g_ysize;
  160.   dev->ncol1 = g_colors;
  161. #endif
  162.  
  163.   if ( pls->xlength && pls->ylength ) {
  164.     dev->xlen = pls->xlength -1;
  165.     dev->ylen = pls->ylength -1;
  166.     if ( dev->ncol1 ) {
  167.       dev->ncol1 -= pls->ncol0; /* subtract colours already in cmap0 */
  168.       if ( dev->ncol1 > pls->ncol1 )
  169.         dev->ncol1 = pls->ncol1;
  170.     }
  171.   } else {
  172.     dev->xlen = dev->ylen = dev->ncol1 = 0;
  173.   }
  174.  
  175.   return mode;
  176. }
  177.  
  178.  
  179. /*----------------------------------------------------------------------*\
  180. * plD_init_vga()
  181. *
  182. * Initialize device.
  183. \*----------------------------------------------------------------------*/
  184.  
  185. void
  186. plD_init_vga(PLStream *pls)
  187. {                               /* ~~~~ */
  188.   vgaDev *dev;
  189.  
  190.   pls->termin = 1;              /* is an interactive terminal */
  191.   pls->icol0 = 1;
  192.   pls->width = 1;
  193.   pls->bytecnt = 0;
  194.   pls->page = 0;
  195.   pls->graphx = 0;
  196.   pls->dev_fill0 = 1;           /* Can do solid fills */
  197.  
  198.   if ( !pls->colorset )
  199.     pls->color = 1;
  200.  
  201. /* Allocate and initialize device-specific data */
  202.   if (pls->dev != NULL)
  203.     free((void *) pls->dev);
  204.  
  205.   pls->dev = calloc(1, (size_t) sizeof(vgaDev));
  206.   if (pls->dev == NULL)
  207.     plexit("plD_init_vga: Out of memory.");
  208.   dev = (vgaDev *) pls->dev;
  209.  
  210.   if ( !g_mode_detect(pls) )
  211.     plexit( "plD_init_vga: No svga card?" );
  212.  
  213.   plP_setpxl( 3.0, 3.0 );       /* pixels per mm */
  214.   plP_setphy(0, dev->xlen, 0, dev->ylen );
  215.  
  216.   pls->graphx = 0;
  217.   vga_graphics(pls);
  218. }
  219.  
  220. /*----------------------------------------------------------------------*\
  221. * plD_line_vga()
  222. *
  223. * Draw a line in the current color from (x1,y1) to (x2,y2).
  224. \*----------------------------------------------------------------------*/
  225.  
  226. void
  227. plD_line_vga(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
  228. {                               /* ~~~~ */
  229.     vgaDev *dev = (vgaDev *) pls->dev;
  230.     dev->isPageDirty = 1;
  231.     g_line ( (int) x1a, (int) (dev->ylen - y1a),
  232.              (int) x2a, (int) (dev->ylen - y2a),
  233.              dev->curcolor );
  234. }
  235.  
  236. /*----------------------------------------------------------------------*\
  237. * plD_polyline_vga()
  238. *
  239. * Draw a polyline in the current color.
  240. \*----------------------------------------------------------------------*/
  241.  
  242. void
  243. plD_polyline_vga(PLStream *pls, short *xa, short *ya, PLINT npts)
  244. {                               /* ~~~~ */
  245.     PLINT i;
  246.     vgaDev *dev = (vgaDev *) pls->dev;
  247.  
  248.     dev->isPageDirty = 1;
  249.     for (i = 0; i < npts - 1; i++)
  250.       g_line( (int) xa[i],      (int) (dev->ylen - ya[i]),
  251.               (int) xa[i + 1],  (int) (dev->ylen - ya[i+1]),
  252.               dev->curcolor );
  253. }
  254.  
  255. /*----------------------------------------------------------------------*\
  256. * plD_eop_vga()
  257. *
  258. * End of page.
  259. \*----------------------------------------------------------------------*/
  260.  
  261. void
  262. plD_eop_vga(PLStream *pls)
  263. {                               /* ~~~~ */
  264.   vgaDev *dev = (vgaDev *) pls->dev;
  265.   if ( dev->isPageDirty ) {
  266.     pause();
  267.     g_clear( 0 );
  268.     dev->isPageDirty = 0;
  269.   }
  270. }
  271.  
  272. /*----------------------------------------------------------------------*\
  273. * plD_bop_vga()
  274. *
  275. * Set up for the next page.
  276. * Advance to next family file if necessary (file output).
  277. \*----------------------------------------------------------------------*/
  278.  
  279. void
  280. plD_bop_vga(PLStream *pls)
  281. {                               /* ~~~~ */
  282.   pls->page++;
  283.   plD_eop_vga(pls);
  284. }
  285.  
  286. /*----------------------------------------------------------------------*\
  287. * plD_tidy_vga()
  288. *
  289. * Close graphics file or otherwise clean up.
  290. \*----------------------------------------------------------------------*/
  291.  
  292. void
  293. plD_tidy_vga(PLStream *pls)
  294. {                               /* ~~~~ */
  295.   vga_text(pls);
  296.   pls->page = 0;
  297.   pls->OutFile = NULL;
  298. }
  299.  
  300. /*----------------------------------------------------------------------*\
  301. * plD_state_vga()
  302. *
  303. * Handle change in PLStream state (color, pen width, fill attribute, etc).
  304. \*----------------------------------------------------------------------*/
  305.  
  306. void
  307. plD_state_vga(PLStream *pls, PLINT op)
  308. {                               /* ~~~~ */
  309.   vgaDev *dev = (vgaDev *) pls->dev;
  310.  
  311.   switch (op) {
  312.   case PLSTATE_WIDTH:   /* pen width */
  313.     break;
  314.  
  315.   case PLSTATE_COLOR0:  /* switch to a color from cmap 0 */
  316.     dev->curcolor = pls->icol0;
  317.     break;
  318.  
  319.   case PLSTATE_COLOR1:  /* switch to a color from cmap 1 */
  320.     dev->curcolor = (pls->icol1 * (dev->ncol1-1)) / (pls->ncol1-1)
  321.         + pls->ncol0;
  322.     break;
  323.  
  324.   case PLSTATE_FILL:    /* set area fill attribute */
  325.     break;
  326.  
  327.   case PLSTATE_CMAP0:   /* change to cmap 0 */
  328.     Cmap0Init(pls);
  329.     break;
  330.  
  331.   case PLSTATE_CMAP1:   /* change to cmap 1 */
  332.     Cmap1Init(pls);
  333.     break;
  334.   }
  335. }
  336.  
  337. /*----------------------------------------------------------------------*\
  338. * plD_esc_vga()
  339. *
  340. * Escape function.
  341. *
  342. * Functions:
  343. *    PLESC_TEXT    change to text mode
  344. *    PLESC_GRAPH    change to graphics mode
  345. *    PLESC_FILL    Fill polygon
  346. *
  347. \*----------------------------------------------------------------------*/
  348.  
  349. void
  350. plD_esc_vga(PLStream *pls, PLINT op, void *ptr)
  351. {                               /* ~~~~ */
  352.   switch (op) {
  353.   case PLESC_TEXT:
  354.     vga_text(pls);
  355.     break;
  356.  
  357.   case PLESC_GRAPH:
  358.     vga_graphics(pls);
  359.     break;
  360.  
  361.   case PLESC_FILL:
  362.     fill_polygon(pls);
  363.     break;
  364.   }
  365. }
  366.  
  367. /*----------------------------------------------------------------------*\
  368. * vga_graphics()
  369. *
  370. * Switch to graphis mode.
  371. \*----------------------------------------------------------------------*/
  372.  
  373. static void
  374. vga_graphics(PLStream *pls)
  375. {                               /* ~~~~ */
  376.   vgaDev *dev = (vgaDev *) pls->dev;
  377.  
  378.   if ( !pls->graphx ) {
  379.     g_mode( dev->VESAmode );
  380.     Cmap0Init(pls);
  381.     Cmap1Init(pls);
  382.     if ( pls->curcmap ) {       /* colour map 1 */
  383.       dev->curcolor = (pls->icol1 * (dev->ncol1-1)) / (pls->ncol1-1)
  384.                 + pls->ncol0;
  385.     } else {
  386.       dev->curcolor = pls->icol0;
  387.     }
  388.     pls->graphx = 1;
  389.     dev->isPageDirty = 0;
  390.   }
  391. }
  392.  
  393.  
  394. /*----------------------------------------------------------------------*\
  395. * vga_text()
  396. *
  397. * Switch to text mode.
  398. \*----------------------------------------------------------------------*/
  399.  
  400. static void
  401. vga_text(PLStream *pls)
  402. {                               /* ~~~~ */
  403.   vgaDev *dev = (vgaDev *) pls->dev;
  404.   if ( pls->graphx ) {
  405.     if ( dev->isPageDirty )
  406.       pause();
  407.     g_mode( GTEXT );
  408.  
  409.     pls->graphx = 0;
  410.     dev->isPageDirty = 0;
  411.   }
  412. }
  413.  
  414. /*----------------------------------------------------------------------*\
  415. * fill_polygon()
  416. *
  417. * Fill polygon described in points pls->dev_x[] and pls->dev_y[].
  418. * Only solid color fill supported.
  419. \*----------------------------------------------------------------------*/
  420.  
  421. static void
  422. fill_polygon(PLStream *pls)
  423. {                               /* ~~~~ */
  424.   int x[PL_MAXPOLY], y[PL_MAXPOLY], n;
  425.   vgaDev *dev = (vgaDev *) pls->dev;
  426.  
  427.   if (pls->dev_npts > PL_MAXPOLY)
  428.     plexit("Error -- too many points in polygon\n");
  429.  
  430.   for (n = 0; n < pls->dev_npts; n++) {
  431.     x[n] = (int) pls->dev_x[n];
  432.     y[n] = (int) (dev->ylen - pls->dev_y[n]);
  433.   }
  434.  
  435.   g_polygon( x, y, n, (dev->curcolor), G_FILL );
  436. }
  437.  
  438. /*----------------------------------------------------------------------*\
  439. * pause()
  440. *
  441. * Wait for a keystroke.
  442. *
  443. * someday, real text - but it works
  444. \*----------------------------------------------------------------------*/
  445.  
  446. static const int
  447.   Px[] = { 0x10, 0x10, 0x00, 0x20, 0x20 },      /* <-| prompt */
  448.   Py[] = { 0x00, 0x10, 0x08, 0x08, 0x00 };
  449.  
  450. static void
  451. pause(void)
  452. {                               /* ~~~~ */
  453.   g_polygon( Px, Py, 3, PROMPT_COLOR, G_FILL );
  454.   g_line( Px[2], Py[2], Px[3], Py[3], PROMPT_COLOR );
  455.   g_line( Px[3], Py[3], Px[4], Py[4], PROMPT_COLOR );
  456.  
  457.   if ( ! _read_kbd(0, 1, 0) )
  458.     _read_kbd(0, 1, 0);
  459. }
  460.  
  461. #else
  462. int
  463. pldummy_emxvga()
  464. {                               /* ~~~~ */
  465.   return 0;
  466. }
  467.  
  468. #endif                          /* (__EMX__) && (EMXVESA) */
  469. /* ///////////////////// end of file (c source) /////////////////// */
  470.